-- drop function if exists sm_sc.fv_activate_leaky_relu(float[], float);
create or replace function sm_sc.fv_activate_leaky_relu
(
  i_array     float[]        ,
  i_asso_value  float    -- 
)
returns float[]
as
$$
-- -- declare -- here
-- --   v_x_cur   int  := 1  ;
-- --   v_y_cur   int  := 1  ;
-- --   v_x3_cur      int  := 1  ;
-- --   v_x4_cur      int  := 1  ;
begin
  if i_asso_value is null 
  then 
    i_asso_value := 0.01;
  end if;
  
  return 
    i_array 
    *` 
    (
      (
        ((1.0 :: float - i_asso_value) / 2.0 :: float)
        *`
        (<>` (<>` i_array :: float[] +` 0.5 :: float))
      )
      +`
      ((1.0 :: float + i_asso_value) / 2.0 :: float)
    )
  ;
  
  -- -- -- leaky_relu(null :: float[][], float) = null :: float[][]
  -- -- if array_length(i_array, array_ndims(i_array)) is null
  -- -- then 
  -- --   return i_array;
  -- -- end if;
  -- -- 
  -- -- -- sm_sc.fv_leaky_relu([][], )
  -- -- if array_ndims(i_array) =  2
  -- -- then
  -- --   while v_y_cur <= array_length(i_array, 1)
  -- --   loop 
  -- --     v_x_cur := 1  ;
  -- --     while v_x_cur <= array_length(i_array, 2)
  -- --     loop
  -- --       i_array[v_y_cur][v_x_cur] := sm_sc.fv_leaky_relu(i_array[v_y_cur][v_x_cur], i_asso_value);
  -- --       v_x_cur := v_x_cur + 1;
  -- --     end loop;
  -- --     v_y_cur := v_y_cur + 1;
  -- --   end loop;
  -- --   return i_array;
  -- -- 
  -- -- -- sm_sc.fv_leaky_relu [],
  -- -- elsif array_ndims(i_array) = 1
  -- -- then
  -- --   while v_y_cur <= array_length(i_array, 1)
  -- --   loop
  -- --     i_array[v_y_cur] := sm_sc.fv_leaky_relu(i_array[v_y_cur], i_asso_value);
  -- --     v_y_cur := v_y_cur + 1;
  -- --   end loop;
  -- --   return i_array;
  -- -- 
  -- -- 
  -- -- -- sm_sc.fv_leaky_relu([][][])
  -- -- elsif array_ndims(i_array) = 3
  -- -- then
  -- --   for v_y_cur in 1 .. array_length(i_array, 1)
  -- --   loop
  -- --     for v_x_cur in 1 .. array_length(i_array, 2)
  -- --     loop
  -- --       for v_x3_cur in 1 .. array_length(i_array, 3)
  -- --       loop
  -- --         i_array[v_y_cur][v_x_cur][v_x3_cur] = 
  -- --           sm_sc.fv_leaky_relu(i_array[v_y_cur][v_x_cur][v_x3_cur], i_asso_value)
  -- --         ;
  -- --       end loop;    
  -- --     end loop;
  -- --   end loop;
  -- --   return i_array;
  -- --   
  -- -- -- sm_sc.fv_leaky_relu([][][][])
  -- -- elsif array_ndims(i_array) = 4
  -- -- then
  -- --   for v_y_cur in 1 .. array_length(i_array, 1)
  -- --   loop
  -- --     for v_x_cur in 1 .. array_length(i_array, 2)
  -- --     loop
  -- --       for v_x3_cur in 1 .. array_length(i_array, 3)
  -- --       loop
  -- --         for v_x4_cur in 1 .. array_length(i_array, 4)
  -- --         loop
  -- --           i_array[v_y_cur][v_x_cur][v_x3_cur][v_x4_cur] = 
  -- --             sm_sc.fv_leaky_relu(i_array[v_y_cur][v_x_cur][v_x3_cur][v_x4_cur], i_asso_value)
  -- --           ;
  -- --         end loop;
  -- --       end loop;    
  -- --     end loop;
  -- --   end loop;
  -- --   return i_array;
  -- --   
  -- -- else
  -- --   raise exception 'no method for such length!  Dims: %;', array_dims(i_array);
  -- -- end if;
end
$$
language plpgsql stable
cost 100;
-- select sm_sc.fv_activate_leaky_relu(array[[1.0 :: float, -2.0], [3.0, 4.0]], 0.3)
-- select sm_sc.fv_activate_leaky_relu(array[[[1.0 :: float, -2.0], [3.0, 4.0]]], 0.3)
-- select sm_sc.fv_activate_leaky_relu(array[[[[1.0 :: float, -2.0], [3.0, 4.0]]]], 0.3)
-- select sm_sc.fv_activate_leaky_relu(array[1.5, -2.5, 3.5], 0.2)
-- select sm_sc.fv_activate_leaky_relu(array[]::float[], 0.2)
-- select sm_sc.fv_activate_leaky_relu(array[array[], array []]::float[], 0.2)